﻿using BizControl.Library.BusinessObjects;
using Csla.Xaml;
using BizControl.Presentation.Infrastructure.Controls;
using Microsoft.Practices.Prism.Regions;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism;
using System;
using BizControl.Presentation.Infrastructure.Constants;
using System.Windows.Input;
using GraphSharp.Controls;
using System.ComponentModel;
using System.Linq;
using BizControl.Library.BusinessObjects.Marks;
using Csla;
using BizControl.Library.Security;
using BizControl.Presentation.Infrastructure.Controls.Graph;
using BizControl.Library.BusinessObjects.Categories;
using QuickGraph;
using GraphSharp;
using System.Collections.Generic;

namespace BizControl.Presentation.GraphModule.ViewModels
{
  [Export]
  public class GraphViewModel : INavigationAware, IRegionMemberLifetime, IGraphViewModel
  {
    public GraphViewModel()
    {
      CreateSampleGraphs();
    }

    public GraphViewModel(bool createSample = true)
    {
      if (createSample)
        CreateSampleGraphs();
    }

    private void CreateSampleGraphs()
    {
      #region SimpleTree

      _graph = new BCGraph();

      GraphViewModel childModel1 = new GraphViewModel(false) { LayoutAlgorithmType = "Tree" };
      GraphViewModel childModel2 = new GraphViewModel(false) { LayoutAlgorithmType = "Tree" };

      var parent1 = new GraphVertex("group", "Group #1");
      var parent2 = new GraphVertex("group", "Group #2");
      _graph.AddVertex(parent1);
      _graph.AddVertex(parent2);
      _graph.AddEdge(new GraphEdge("0to1", parent1, parent2));

      childModel1.Graph = new BCGraph();
      string[] s_vertices = { "Hello", "World", "I", "am", "Happy", "To", "Live", "Here" };
      for (int i = 0; i < 8; i++)
      {
        childModel1.Graph.AddVertex(new GraphVertex("default", s_vertices[i]));
      }

      childModel1.Graph.AddEdge(new GraphEdge("0to1", childModel1.Graph.Vertices.ElementAt(0), childModel1.Graph.Vertices.ElementAt(1)));
      childModel1.Graph.AddEdge(new GraphEdge("1to2", childModel1.Graph.Vertices.ElementAt(1), childModel1.Graph.Vertices.ElementAt(2)));
      childModel1.Graph.AddEdge(new GraphEdge("2to3", childModel1.Graph.Vertices.ElementAt(2), childModel1.Graph.Vertices.ElementAt(3)));
      childModel1.Graph.AddEdge(new GraphEdge("2to4", childModel1.Graph.Vertices.ElementAt(2), childModel1.Graph.Vertices.ElementAt(4)));
      childModel1.Graph.AddEdge(new GraphEdge("0to5", childModel1.Graph.Vertices.ElementAt(0), childModel1.Graph.Vertices.ElementAt(5)));
      childModel1.Graph.AddEdge(new GraphEdge("1to7", childModel1.Graph.Vertices.ElementAt(1), childModel1.Graph.Vertices.ElementAt(7)));
      childModel1.Graph.AddEdge(new GraphEdge("4to6", childModel1.Graph.Vertices.ElementAt(4), childModel1.Graph.Vertices.ElementAt(6)));

      childModel2.Graph = new BCGraph();
      var currentUser = (ApplicationContext.User as BizControlPrincipal).Person;
      var userVertex = new GraphVertex("user", currentUser);
      childModel2.Graph.AddVertex(userVertex);
      foreach (var mark in currentUser.Marks)
      {
        var markBO = PersonMarkBO.GetPersonMark(mark.Mark.Id);
        var markVertex = new GraphVertex("mark", markBO);
        childModel2.Graph.AddVertex(markVertex);
        childModel2.Graph.AddEdge(new GraphEdge(currentUser.Login + " " + markBO.Name, markBO, userVertex, markVertex));
      }

      parent1.ChildModel = childModel1;
      parent2.ChildModel = childModel2;

      #endregion

      LayoutAlgorithmType = "Tree";
      //LayoutAlgorithmType = "FR";
      //LayoutAlgorithmType = "CompoundFDP";
    }

    private bool _isSelected;
    public bool IsSelected
    {
      get { return _isSelected; }
      set
      {
        if (value != _isSelected)
        {
          _isSelected = value;
          NotifyChanged("IsSelected");
        }
      }
    }

    private string _layoutAlgorithmType;
    public string LayoutAlgorithmType
    {
      get { return _layoutAlgorithmType; }
      set
      {
        if (value != _layoutAlgorithmType)
        {
          _layoutAlgorithmType = value;
          NotifyChanged("LayoutAlgorithmType");
        }
      }
    }

    private BCGraph _graph;
    public BCGraph Graph
    {
      get { return _graph; }
      set
      {
        if (value != _graph)
        {
          _graph = value;
          NotifyChanged("Graph");
        }
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyChanged(string propertyName)
    {
      if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #region INavigationAware Members

    public bool IsNavigationTarget(NavigationContext navigationContext)
    {
      return true;
    }

    public void OnNavigatedFrom(NavigationContext navigationContext)
    {
    }

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
    }

    #endregion

    #region IRegionMemberLifetime Members

    public bool KeepAlive
    {
      get { return true; }
    }

    #endregion

  }
}
